package com.sxf.core.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.sxf.auth.enums.CommonStatusEnum;
import com.sxf.auth.enums.UserStatusEnum;
import com.sxf.auth.enums.UserTypeEnum;
import com.sxf.auth.login.model.AuthUser;
import com.sxf.auth.login.service.UserService;
import com.sxf.auth.login.vo.LoginRes;
import com.sxf.cache.Ehcache2Cache;
import com.sxf.common.enums.ErrorCodeEnum;
import com.sxf.common.exceptions.BusinessException;
import com.sxf.consts.YtConsts;
import com.sxf.core.aspect.ClientThreadLocal;
import com.sxf.core.aspect.UserThreadLocal;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description token权限拦截
 * @author villain
 * @date 2022年4月15日 上午9:46:04
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {

    private final Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);

    private Cache tokenCache = Ehcache2Cache.initCache("token");

    @Autowired
    UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        String token = request.getHeader(YtConsts.REQUEST_HEADER_TOKEN_KEY);

        if(ObjectUtil.isNull(token)) {
            throw new BusinessException(ErrorCodeEnum.TOKEN_CHECK_ERROR);
        }
        //client校验
        String client = request.getHeader(YtConsts.REQUEST_HEADER_CLIENT);
        if(StringUtils.isEmpty(client)){
            throw new BusinessException(ErrorCodeEnum.UNAUTHORIZED_ERROR);
        }

        List<String> clientTypes = Arrays.stream(UserTypeEnum.values()).map(UserTypeEnum::getCode).collect(Collectors.toList());
        if(!clientTypes.contains(client)){
            throw new BusinessException(ErrorCodeEnum.UNAUTHORIZED_ERROR);
        }
        Element tokenElement = tokenCache.get(YtConsts.USER_TOKEN_KEY + token);
        if(tokenElement == null){
            throw new BusinessException(ErrorCodeEnum.TOKEN_CHECK_ERROR);
        }
        LoginRes loginRes = (LoginRes) tokenElement.getObjectValue();

        //缓存过期 直接token失效
        if (Objects.isNull(loginRes)){
            throw new BusinessException(ErrorCodeEnum.TOKEN_CHECK_ERROR);
        }
        //人和客户端是否匹配
        if(!loginRes.getUserType().equals(client)){
            throw new BusinessException(ErrorCodeEnum.UNAUTHORIZED_ERROR);
        }

        //用户状态判断
        AuthUser authUser = userService.getById(loginRes.getPkUser());
        if(UserStatusEnum.INVALID.getCode().equals(authUser.getStatus())){
            //用户状态被禁用
            throw new BusinessException(ErrorCodeEnum.USER_FREEZE_ERROR);
        }

        if(UserStatusEnum.LOGOFF.getCode().equals(authUser.getStatus())){
            //用户已经注销
            throw new BusinessException(ErrorCodeEnum.USER_CANCEL_ERROR);
        }

        UserThreadLocal.set(loginRes);
        ClientThreadLocal.set(client);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserThreadLocal.remove();
        ClientThreadLocal.remove();
    }

}
